home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / WINGs / wfont.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-09  |  7.3 KB  |  366 lines

  1.  
  2. #include "WINGsP.h"
  3.  
  4.  
  5. #include <wraster.h>
  6. #include <assert.h>
  7.  
  8. static char *makeFontSetOfSize(char *fontset, int size);
  9.  
  10.  
  11. WMFont*
  12. WMCreateFontSet(WMScreen *scrPtr, char *fontName)
  13. {
  14.     WMFont *font;
  15.     Display *display = scrPtr->display;
  16.     char **missing;
  17.     int nmissing = 0;
  18.     char *defaultString;
  19.     XFontSetExtents *extents;
  20.  
  21.     font = WMHashGet(scrPtr->fontCache, fontName);
  22.     if (font) {
  23.     WMRetainFont(font);
  24.     return font;
  25.     }
  26.  
  27.     font = malloc(sizeof(WMFont));
  28.     if (!font)
  29.       return NULL;
  30.     memset(font, 0, sizeof(WMFont));
  31.  
  32.     font->notFontSet = 0;
  33.  
  34.     font->screen = scrPtr;
  35.  
  36.     font->font.set = XCreateFontSet(display, fontName, &missing, &nmissing,
  37.                     &defaultString);
  38.     if (nmissing > 0 && font->font.set) {
  39.     int i;
  40.     
  41.     wwarning("the following character sets are missing in %s:",
  42.          fontName);
  43.     for (i = 0; i < nmissing; i++) {
  44.         wwarning(missing[i]);
  45.     }
  46.     XFreeStringList(missing);
  47.     if (defaultString)
  48.         wwarning("the string \"%s\" will be used in place of any characters from those sets.",
  49.              defaultString);
  50.     }
  51.     if (!font->font.set) {
  52.     wfree(font);
  53.     return NULL;
  54.     }
  55.     
  56.     extents = XExtentsOfFontSet(font->font.set);
  57.     
  58.     font->height = extents->max_logical_extent.height;
  59.     font->y = font->height - (font->height + extents->max_logical_extent.y);
  60.  
  61.     font->refCount = 1;
  62.  
  63.     font->name = wstrdup(fontName);
  64.  
  65.     assert(WMHashInsert(scrPtr->fontCache, font->name, font)==NULL);
  66.  
  67.     return font;
  68. }
  69.  
  70.  
  71.  
  72. WMFont*
  73. WMCreateNormalFont(WMScreen *scrPtr, char *fontName)
  74. {
  75.     WMFont *font;
  76.     Display *display = scrPtr->display;
  77.     char *fname, *ptr;
  78.  
  79.     if ((ptr = strchr(fontName, ','))) {
  80.     fname = wmalloc(ptr - fontName + 1);
  81.     strncpy(fname, fontName, ptr - fontName);
  82.     fname[ptr - fontName] = 0;
  83.     } else {
  84.     fname = wstrdup(fontName);
  85.     }
  86.  
  87.     font = WMHashGet(scrPtr->fontCache, fname);
  88.     if (font) {
  89.     WMRetainFont(font);
  90.     wfree(fname);
  91.     return font;
  92.     }
  93.  
  94.     font = malloc(sizeof(WMFont));
  95.     if (!font) {
  96.     wfree(fname);
  97.     return NULL;
  98.     }
  99.     memset(font, 0, sizeof(WMFont));
  100.     
  101.     font->notFontSet = 1;
  102.     
  103.     font->screen = scrPtr;
  104.     
  105.     font->font.normal = XLoadQueryFont(display, fname);
  106.     if (!font->font.normal) {
  107.     wfree(font);
  108.     return NULL;
  109.     }
  110.  
  111.     font->height = font->font.normal->ascent+font->font.normal->descent;
  112.     font->y = font->font.normal->ascent;
  113.  
  114.     font->refCount = 1;
  115.  
  116.     font->name = fname;
  117.  
  118.     assert(WMHashInsert(scrPtr->fontCache, font->name, font)==NULL);
  119.  
  120.     return font;
  121. }
  122.  
  123.  
  124.  
  125. WMFont*
  126. WMCreateFont(WMScreen *scrPtr, char *fontName)
  127. {
  128.     if (scrPtr->useMultiByte)
  129.     return WMCreateFontSet(scrPtr, fontName);
  130.     else
  131.     return WMCreateNormalFont(scrPtr, fontName);
  132. }
  133.  
  134.  
  135.  
  136. WMFont*
  137. WMRetainFont(WMFont *font)
  138. {
  139.     wassertrv(font!=NULL, NULL);
  140.  
  141.     font->refCount++;
  142.  
  143.     return font;
  144. }
  145.  
  146.  
  147. void 
  148. WMReleaseFont(WMFont *font)
  149. {
  150.     wassertr(font!=NULL);
  151.  
  152.     font->refCount--;
  153.     if (font->refCount < 1) {
  154.     if (font->notFontSet)
  155.         XFreeFont(font->screen->display, font->font.normal);
  156.     else {
  157.         XFreeFontSet(font->screen->display, font->font.set);
  158.     }
  159.     if (font->name) {
  160.         WMHashRemove(font->screen->fontCache, font->name);
  161.         wfree(font->name);
  162.     }
  163.     wfree(font);
  164.     }
  165. }
  166.  
  167.  
  168.  
  169. unsigned int
  170. WMFontHeight(WMFont *font)
  171. {
  172.     wassertrv(font!=NULL, 0);
  173.  
  174.     return font->height;
  175. }
  176.  
  177.  
  178.  
  179. WMFont*
  180. WMSystemFontOfSize(WMScreen *scrPtr, int size)
  181. {
  182.     WMFont *font;
  183.     char *fontSpec;
  184.  
  185.     fontSpec = makeFontSetOfSize(WINGsConfiguration.systemFont, size);
  186.  
  187.     if (scrPtr->useMultiByte)
  188.     font = WMCreateFontSet(scrPtr, fontSpec);
  189.     else
  190.     font = WMCreateNormalFont(scrPtr, fontSpec);
  191.  
  192.     if (!font) {
  193.     if (scrPtr->useMultiByte) {
  194.         wwarning("could not load font set %s. Trying fixed.", fontSpec);
  195.         font = WMCreateFontSet(scrPtr, "fixed");
  196.         if (!font) {
  197.         font = WMCreateFontSet(scrPtr, "-*-fixed-medium-r-normal-*-14-*-*-*-*-*-*-*");
  198.         }
  199.     } else {
  200.         wwarning("could not load font %s. Trying fixed.", fontSpec);
  201.         font = WMCreateNormalFont(scrPtr, "fixed");
  202.     }
  203.     if (!font) {
  204.         wwarning("could not load fixed font!");
  205.         wfree(fontSpec);
  206.         return NULL;
  207.     }
  208.     }
  209.     wfree(fontSpec);
  210.  
  211.     return font;
  212. }
  213.  
  214.  
  215. WMFont*
  216. WMBoldSystemFontOfSize(WMScreen *scrPtr, int size)
  217. {
  218.     WMFont *font;
  219.     char *fontSpec;
  220.  
  221.     fontSpec = makeFontSetOfSize(WINGsConfiguration.boldSystemFont, size);
  222.  
  223.     if (scrPtr->useMultiByte)
  224.     font = WMCreateFontSet(scrPtr, fontSpec);
  225.     else
  226.     font = WMCreateNormalFont(scrPtr, fontSpec);
  227.  
  228.     if (!font) {
  229.     if (scrPtr->useMultiByte) {
  230.         wwarning("could not load font set %s. Trying fixed.", fontSpec);
  231.         font = WMCreateFontSet(scrPtr, "fixed");
  232.         if (!font) {
  233.         font = WMCreateFontSet(scrPtr, "-*-fixed-medium-r-normal-*-14-*-*-*-*-*-*-*");
  234.         }
  235.     } else {
  236.         wwarning("could not load font %s. Trying fixed.", fontSpec);
  237.         font = WMCreateNormalFont(scrPtr, "fixed");
  238.     }
  239.     if (!font) {
  240.         wwarning("could not load fixed font!");
  241.         wfree(fontSpec);
  242.         return NULL;
  243.     }
  244.     }
  245.     wfree(fontSpec);
  246.     
  247.     return font;
  248. }
  249.  
  250.  
  251. XFontSet
  252. WMGetFontFontSet(WMFont *font)
  253. {
  254.     wassertrv(font!=NULL, NULL);
  255.  
  256.     if (font->notFontSet)
  257.     return NULL;
  258.     else
  259.     return font->font.set;
  260. }
  261.  
  262.  
  263. int
  264. WMWidthOfString(WMFont *font, char *text, int length)
  265. {
  266.     wassertrv(font!=NULL, 0);
  267.     wassertrv(text!=NULL, 0);
  268.     
  269.     if (font->notFontSet)
  270.     return XTextWidth(font->font.normal, text, length);
  271.     else {
  272.     XRectangle rect;
  273.     XRectangle AIXsucks;
  274.     
  275.     XmbTextExtents(font->font.set, text, length, &AIXsucks, &rect);
  276.     
  277.     return rect.width;
  278.     }
  279. }
  280.  
  281.  
  282.  
  283. void
  284. WMDrawString(WMScreen *scr, Drawable d, GC gc, WMFont *font, int x, int y,
  285.          char *text, int length)
  286. {
  287.     wassertr(font!=NULL);
  288.  
  289.     if (font->notFontSet) {
  290.     XSetFont(scr->display, gc, font->font.normal->fid);
  291.     XDrawString(scr->display, d, gc, x, y + font->y, text, length);
  292.     } else {
  293.     XmbDrawString(scr->display, d, font->font.set, gc, x, y + font->y,
  294.               text, length);
  295.     }
  296. }
  297.  
  298.  
  299. void
  300. WMDrawImageString(WMScreen *scr, Drawable d, GC gc, WMFont *font, int x, int y,
  301.           char *text, int length)
  302. {
  303.     wassertr(font != NULL);
  304.  
  305.     if (font->notFontSet) {
  306.     XSetFont(scr->display, gc, font->font.normal->fid);
  307.     XDrawImageString(scr->display, d, gc, x, y + font->y, text, length);
  308.     } else {
  309.     XmbDrawImageString(scr->display, d, font->font.set, gc, x, y + font->y,
  310.                text, length);
  311.     }
  312. }
  313.  
  314.  
  315.  
  316.  
  317. static char*
  318. makeFontSetOfSize(char *fontset, int size)
  319. {
  320.     char font[300], *f;
  321.     char *newfs = NULL;
  322.     char *ptr;
  323.  
  324.     do {
  325.     char *tmp;
  326.     int end;
  327.  
  328.  
  329.     f = fontset;
  330.     ptr = strchr(fontset, ',');
  331.     if (ptr) {
  332.         int count = ptr-fontset;
  333.  
  334.         if (count > 255) {
  335.         wwarning("font description %s is too large.", fontset);
  336.         } else {
  337.         memcpy(font, fontset, count);
  338.         font[count] = 0;
  339.         f = (char*)font;
  340.         }
  341.     }
  342.  
  343.     if (newfs)
  344.         end = strlen(newfs);
  345.     else
  346.         end = 0;
  347.  
  348.     tmp = wmalloc(end + strlen(f) + 8);
  349.     if (end != 0) {
  350.         sprintf(tmp, "%s,", newfs);
  351.         sprintf(tmp + end + 1, f, size);
  352.     } else {
  353.         sprintf(tmp + end, f, size);
  354.     }
  355.  
  356.     if (newfs)
  357.         wfree(newfs);
  358.     newfs = tmp;
  359.  
  360.     fontset = ptr+1;
  361.     } while (ptr!=NULL);
  362.  
  363.     return newfs;
  364. }
  365.  
  366.